/**
 * 矩形的包含判断
 * @param outRect :{x:number,y:number,width:number,height:number}   包含者
 * @param innerRect :{x:number,y:number,width:number,height:number}   被包含者
 * @returns : boolean   表示包含者是否包含被包含者
 *
 * # 注意
 * 包含及相等都属于包含
 */
export function rectIsContain(outRect, innerRect) {
  var left = outRect.x <= innerRect.x;
  var right = outRect.width >= innerRect.width;
  var top = outRect.y <= innerRect.y;
  var bottom = outRect.height <= innerRect.height;

  return left && right && top && bottom;
}

/**
 * 矩形的相交或包含判断
 * @param rect1 :{x:number,y:number,width:number,height:number}   矩形1
 * @param rect2 :{x:number,y:number,width:number,height:number}   矩形2
 * @returns : boolean   表示矩形1与矩形2是否相交或包含
 *
 * 注意
 * 不包含相切
 */
export function rectIsCrossOrContain(rect1, rect2) {
  var rt1Left = rect1.x,
      rt1Top = rect1.y,
      rt1Width = rect1.width,
      rt1Height = rect1.height;

  var rt1Right = rt1Left + rt1Width;
  var rt1Bottom = rt1Top + rt1Height;

  var rt2Left = rect2.x,
      rt2Top = rect2.y,
      rt2Width = rect2.width,
      rt2Height = rect2.height;

  var rt2Right = rt2Left + rt2Width;
  var rt2Bottom = rt2Top + rt2Height;

  var max = Math.max;
  var min = Math.min;

  var maxLeft = max(rt1Left, rt2Left);
  var maxTop = max(rt1Top, rt2Top);
  var minRight = min(rt1Right, rt2Right);
  var minBottom = min(rt1Bottom, rt2Bottom);

  var horCross = maxLeft < minRight;
  var verCross = maxTop < minBottom;

  return horCross && verCross;
}

/**
 * 矩形水平方向上的相交或包含判断
 * @param rect1 :{x:number,y:number,width:number,height:number}   矩形1
 * @param rect2 :{x:number,y:number,width:number,height:number}   矩形2
 * @returns : boolean   表示矩形1与矩形2在水平方向上是否相交或包含
 *
 * 注意
 * 不包含相切
 */
export function rectIsCrossOrContainOnHor(rect1, rect2) {
  var rt1Left = rect1.x,
      rt1Width = rect1.width;

  var rt1Right = rt1Left + rt1Width;

  var rt2Left = rect2.x,
      rt2Width = rect2.width;

  var rt2Right = rt2Left + rt2Width;

  var maxLeft = Math.max(rt1Left, rt2Left);
  var minRight = Math.min(rt1Right, rt2Right);

  return maxLeft < minRight;
}

/**
 * 矩形垂直方向上的相交或包含判断
 * @param rect1 :{x:number,y:number,width:number,height:number}   矩形1
 * @param rect2 :{x:number,y:number,width:number,height:number}   矩形2
 * @returns : boolean   表示矩形1与矩形2在垂直方向上是否相交或包含
 *
 * 注意
 * 不包含相切
 */
export function rectIsCrossOrContainOnVer(rect1, rect2) {
  var rt1Top = rect1.y,
      rt1Height = rect1.height;

  var rt1Bottom = rt1Top + rt1Height;

  var rt2Top = rect2.y,
      rt2Height = rect2.height;

  var rt2Bottom = rt2Top + rt2Height;

  var maxTop = Math.max(rt1Top, rt2Top);
  var minBottom = Math.min(rt1Bottom, rt2Bottom);

  return maxTop < minBottom;
}

/**
 * 判断在水平方向上 frontRect 是否在 backRect 的前面，且不相交
 * @param frontRect :{x:number,y:number,width:number,height:number}   前面的矩形
 * @param backRect :{x:number,y:number,width:number,height:number}   后面的矩形
 * @returns : boolean   表示在水平方向上 frontRect 是否在 backRect 的前面，且不相交；
 *
 * 注意
 * 包含相切
 */
export function rectIsInFrontOnHor(frontRect, backRect) {
  var frontRight = frontRect.x + frontRect.width;
  return frontRight <= backRect.x;
}

/**
 * 判断在垂直方向上 frontRect 是否在 backRect 的前面，且不相交
 * @param frontRect :{x:number,y:number,width:number,height:number}   前面的矩形
 * @param backRect :{x:number,y:number,width:number,height:number}   后面的矩形
 * @returns : boolean   表示在垂直方向上 frontRect 是否在 backRect 的前面，且不相交；
 *
 * 注意
 * 包含相切
 */
export function rectIsInFrontOnVer(frontRect, backRect) {
  var frontBottom = frontRect.y + frontRect.height;
  return frontBottom <= backRect.y;
}

/**
 * 矩形的相交判断
 * @param rect1 :{x:number,y:number,width:number,height:number}   矩形1
 * @param rect2 :{x:number,y:number,width:number,height:number}   矩形2
 * @returns : boolean   表示矩形1与矩形2是否相交
 *
 * # 注意
 * 包含不属于相交
 */
export function rectIsCross(rect1, rect2) {
  var crossOrContain = rectIsCrossOrContain(rect1, rect2);
  var contain2 = rectIsContain(rect1, rect2);
  var contain1 = rectIsContain(rect2, rect1);

  return crossOrContain && !contain2 && !contain1;
}

/**
 * 矩形的相切
 * @param rect1 :{x:number,y:number,width:number,height:number}   矩形1
 * @param rect2 :{x:number,y:number,width:number,height:number}   矩形2
 * @returns : boolean   表示矩形1与矩形2是否相切
 *
 */
export function rectIstTangent(rect1, rect2) {
  var rt1Left = rect1.x,
      rt1Top = rect1.y,
      rt1Width = rect1.width,
      rt1Height = rect1.height;

  var rt1Right = rt1Left + rt1Width;
  var rt1Bottom = rt1Top + rt1Height;

  var rt2Left = rect2.x,
      rt2Top = rect2.y,
      rt2Width = rect2.width,
      rt2Height = rect2.height;

  var rt2Right = rt2Left + rt2Width;
  var rt2Bottom = rt2Top + rt2Height;

  var isCrossOrContain = rectIsCrossOrContain(rect1, rect2);

  //判断单边是否相切
  var rt1L = rt1Right === rt2Left;
  var rt1R = rt1Left === rt2Right;
  var rt1T = rt1Bottom === rt2Top;
  var rt1B = rt1Top === rt2Bottom;

  //判断是否有相切的边
  var haveTangent = rt1L || rt1R || rt1T || rt1B;

  return !isCrossOrContain && haveTangent;
}

/**
 * 判断点是否在矩形内
 * @param point :{x:number,y:number}   点
 * @param rect :{x:number,y:number,width:number,height:number}   矩形
 * @returns : boolean
 *
 * # 注意
 * 不包含 点 在 矩形边上的情况
 */
export function pointInRect(point, rect) {
  var left = rect.x,
      top = rect.y,
      width = rect.width,
      height = rect.height;

  var right = left + width;
  var bottom = top + height;

  var px = point.x,
      py = point.y;


  var pL = left < px;
  var pR = px < right;
  var pT = top < py;
  var pB = py < bottom;

  return pL && pR && pT && pB;
}

/**
 * 判断点是否在矩形上
 * @param point :{x:number,y:number}   点
 * @param rect :{x:number,y:number,width:number,height:number}   矩形
 * @returns : boolean
 *
 * # 注意
 * 包含 点 在 矩形边上的情况
 */
export function pointOnRect(point, rect) {
  var left = rect.x,
      top = rect.y,
      width = rect.width,
      height = rect.height;

  var right = left + width;
  var bottom = top + height;

  var px = point.x,
      py = point.y;


  var pL = left <= px;
  var pR = px <= right;
  var pT = top <= py;
  var pB = py <= bottom;

  return pL && pR && pT && pB;
}

/**
 * 判断点是否在矩形的边框上
 * @param point :{x:number,y:number}   点
 * @param rect :{x:number,y:number,width:number,height:number}   矩形
 * @returns : boolean   表示是否在矩形的边框上
 *
 */
export function pointOnRectBorder(point, rect) {
  var onRect = pointOnRect(point, rect);
  var inRect = pointInRect(point, rect);

  return !inRect && onRect;
}

/**
 * 扩展矩形
 * @param rect :{x:number,y:number,width:number,height:number} 原矩形
 * @param horExtendRadius : number 水平扩展半径
 * @param verExtendRadius : number 垂直扩展半径
 * @returns : {x: number, y: number, width: number, height: number}  扩展后的矩形
 */
export function extendRect(rect, horExtendRadius, verExtendRadius) {
  var x = rect.x,
      y = rect.y,
      width = rect.width,
      height = rect.height;

  x = x - horExtendRadius;
  y = y - verExtendRadius;
  width = width + horExtendRadius * 2;
  height = height + verExtendRadius * 2;
  return { x: x, y: y, width: width, height: height };
}